package no.weather.widget;

import java.util.ArrayList;
import java.util.List;

import no.weather.WeatherStation;
import no.weather.WeatherType;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

/**
 * @author torstein
 * 
 */
/**
 * @author torstein
 * 
 */
public class WidgetDatabase {
	private static final String LOG_ID = "no.weather.widget.WidgetDatabase";
	public static final String STATION_ID = "station_id";
	public static final String STATION_NAME = "station_name";
	public static final String STATION_PROVIDER = "station_provider";
	private static final String STATION_TABLE_NAME = "station";
	public static final String WEATHER_TYPES_CODE = "weather_types_code";
	private static final String WEATHER_TYPES_TABLE_NAME = "weather_types";
	private static final String WIDGET_ID = "widget_id";
	private final WidgetDatabaseHelper mDB;

	public WidgetDatabase(Context context) {
		super();
		mDB = new WidgetDatabaseHelper(context);
	}

	private void addStation(int widgetId, String stationId,
			String stationProvider, String stationName) {
		ContentValues values = new ContentValues();
		values.put(WIDGET_ID, widgetId);
		values.put(STATION_ID, stationId);
		values.put(STATION_PROVIDER, stationProvider);
		values.put(STATION_NAME, stationName);
		mDB.getWritableDatabase().insert(STATION_TABLE_NAME, null, values);
		close();
	}

	private void addWeatherType(int widgetId, WeatherType type) {
		ContentValues values = new ContentValues();
		values.put(WIDGET_ID, widgetId);
		values.put(WEATHER_TYPES_CODE, type.getCode());
		mDB.getWritableDatabase()
				.insert(WEATHER_TYPES_TABLE_NAME, null, values);
		close();

	}

	/**
	 * Adds a widget to the database
	 * 
	 * @param widgetId
	 * @param stationId
	 * @param stationProvider
	 * @param stationName
	 * @param types
	 *            Weather types
	 */
	public void addWidget(int widgetId, String stationId,
			String stationProvider, String stationName, WeatherType types[]) {
		addStation(widgetId, stationId, stationProvider, stationName);
		for (WeatherType weatherType : types) {
			addWeatherType(widgetId, weatherType);
		}
	}

	/** Closes all connections to database, use this after a query */
	public void close() {
		mDB.close();
	}

	/**
	 * @return all widget ids in the database or null if empty
	 */
	public int[] getAllWidgetIds() {
		String columns[] = new String[] { WIDGET_ID };
		Cursor c = mDB.getReadableDatabase().query(WEATHER_TYPES_TABLE_NAME,
				columns, null, null, null, null, null);

		if (c == null || c.getCount() == 0)
			return null;

		int[] ids = new int[c.getCount()];
		final int elementCulumn = c.getColumnIndex(WIDGET_ID);
		c.moveToFirst();
		for (int i = 0; i < c.getCount(); i++) {
			ids[i] = c.getInt(elementCulumn);
			c.moveToNext();
		}
		c.close();
		close();
		return ids;
	}

	private List<WeatherType> getTypes(int widgetId) {
		String columns[] = new String[] { WEATHER_TYPES_CODE };
		String selection = WIDGET_ID + "=" + Integer.toString(widgetId);
		Cursor c = mDB.getReadableDatabase().query(WEATHER_TYPES_TABLE_NAME,
				columns, selection, null, null, null, null);

		List<WeatherType> types = new ArrayList<WeatherType>(c.getCount());
		final int elementCulumn = c.getColumnIndex(WEATHER_TYPES_CODE);

		c.moveToFirst();
		for (int i = 0; i < c.getCount(); i++) {
			WeatherType t = new WeatherType();
			String code = c.getString(elementCulumn);
			t.setCode(code);
			types.add(t);
		}
		c.close();
		close();
		return types;
	}

	private WeatherStation getWeatherStation(int widgetId) {

		String columns[] = new String[] { STATION_ID, STATION_PROVIDER,
				STATION_NAME };
		String selection = WIDGET_ID + "=" + Integer.toString(widgetId);
		Cursor c = mDB.getReadableDatabase().query(STATION_TABLE_NAME, columns,
				selection, null, null, null, null);
		if (c == null || c.getCount() == 0)
			return null;

		c.moveToFirst();
		WeatherStation station = new WeatherStation();
		station.setProvider(c.getString(c.getColumnIndex(STATION_PROVIDER)));
		station.setId(c.getString(c.getColumnIndex(STATION_ID)));
		station.setName(c.getString(c.getColumnIndex(STATION_NAME)));

		// Closing database
		c.close();
		close();
		return station;
	}

	/**
	 * @param widgetId
	 *            widget id
	 * @return weather station with types connected to the widget or null if not
	 *         found
	 */
	public WeatherStation getWeatherStationWithWeatherTypes(int widgetId) {
		WeatherStation returnStation = getWeatherStation(widgetId);
		if (returnStation == null)
			return null;

		returnStation.setTypes(getTypes(widgetId));
		return returnStation;
	}

	private void removeStation(int widgetId) {
		String whereClause = WIDGET_ID + "=" + widgetId;
		mDB.getWritableDatabase().delete(STATION_TABLE_NAME, whereClause, null);
		close();

	}

	private void removeTypes(int widgetId) {
		String whereClause = WIDGET_ID + "=" + widgetId;
		mDB.getWritableDatabase().delete(WEATHER_TYPES_TABLE_NAME, whereClause,
				null);
		close();

	}

	/**
	 * @param widgetId
	 *            id for widget to be removed
	 */
	public void removeWidget(int widgetId) {
		removeStation(widgetId);
		removeTypes(widgetId);
	}

	private class WidgetDatabaseHelper extends SQLiteOpenHelper {

		private static final String DATABASE_NAME = "widget.db";
		private static final int DATABASE_VERSION = 1;

		private static final String STATION_TABLE_CREATE = "CREATE TABLE "
				+ STATION_TABLE_NAME + " (_id INTEGER PRIMARY KEY, "
				+ WIDGET_ID + " INTEGER, " + STATION_ID + " TEXT, "
				+ STATION_NAME + " TEXT, " + STATION_PROVIDER + " TEXT)";

		private static final String WEATHER_TYPES_TABLE_CREATE = "CREATE TABLE "
				+ WEATHER_TYPES_TABLE_NAME
				+ " (_id INTEGER PRIMARY KEY, "
				+ WIDGET_ID + " INTEGER, " + WEATHER_TYPES_CODE + " TEXT)";

		public WidgetDatabaseHelper(Context context) {
			super(context, DATABASE_NAME, null, DATABASE_VERSION);
		}

		public WidgetDatabaseHelper(Context context, String name,
				CursorFactory factory, int version) {
			super(context, name, factory, version);
		}

		@Override
		public void onCreate(SQLiteDatabase db) {
			db.execSQL(STATION_TABLE_CREATE);
			db.execSQL(WEATHER_TYPES_TABLE_CREATE);

		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			Log.v(LOG_ID, "Updates database from " + oldVersion + " to "
					+ newVersion);
			db.execSQL("DROP TABLE IF EXISTS " + WEATHER_TYPES_TABLE_NAME);
			db.execSQL("DROP TABLE IF EXISTS " + STATION_TABLE_NAME);
			onCreate(db);
		}

	}

}
